
import allure
import pymysql
import requests
import jsonpath
from core.globalContext import G_context
from deepdiff import DeepDiff
from pymysql import cursors


class Keyword:
    @allure.step("请求消息发送")
    def request_post(self,**kwargs):
        response=requests.post(**kwargs)
        G_context().set_dict('response',response)
        return response

    @allure.step ("get消息发送")
    def request_get(self,**kwargs):
        response=requests.post(**kwargs)
        G_context().set_dict('response', response)
        return response

    @allure.step ("put消息发送")
    def request_put(self,**kwargs):
        response=requests.put(**kwargs)
        G_context ().set_dict ('response', response)
        return response

    @allure.step ("获取json 文件中的字段")
    def exp_jsonfile(self, **kwargs):
        EXVALUE = kwargs.get("EXVALUE", None)
        INDEX = kwargs.get("INDEX", None)
        if INDEX is None:
            INDEX = 0
        response = G_context().get_dict('response').json()
        exp_data = jsonpath.jsonpath(response, EXVALUE)[INDEX]
        G_context().set_dict(kwargs['VARNAME'], exp_data)
        return exp_data

    @allure.step("响应结果中部分内容的断言")
    def assert_exp_result(self,**kwargs):
        message = kwargs.get("message", None)
        comparater = {
            '==': lambda a, b: a == b,
            '!=': lambda a, b: a != b,
            '>': lambda a, b: a > b,
            '<': lambda a, b: a < b,
            '>=': lambda a, b: a >= b,
            '<=': lambda a, b: a <= b
        }
        if kwargs['OP_STR'] not in comparater.keys():
            raise ValueError("不支持该操作方式：",kwargs['OP_STR'])
        if not comparater[kwargs['OP_STR']] (kwargs['VALUE'], kwargs["EXPECTED"]):
            if message:
                raise AssertionError (message)
            else:
                raise AssertionError (f"{kwargs['VALUE']} {kwargs['OP_STR']} {kwargs['EXPECTED']} 失败")

    @allure.step ("提取数据库中的数据进行断言")
    def exp_mysqldata(self, **kwargs):
        database = G_context().get_dict('_database')['mysql001']
        #database = kwargs.get("_database", None)
        send_data={"cursorclass": cursors.DictCursor}

        database.update(send_data)
        #链接数据库
        connection = pymysql.connect(**database)
        #创建游标对象
        cursor = connection.cursor()
        sql = kwargs['SQL']
        #. 使用游标对象去执行操作SQL
        cursor.execute(sql)
        #返回所有数据
        response = cursor.fetchall()
        #关闭游标
        cursor.close ()
        #关闭数据库
        connection.close ()
        #打印数据量返回结果
        print('数据库返回',response)

        var_names = kwargs["引用变量"].split (",")
        print('dayinchulai 你是个什么东西',var_names)
        result = {}
        for i, data in enumerate (response, start=0):
            for j, value in enumerate (var_names,):
                result[f'{var_names[j]}_{i}'] = data.get(var_names[j])  # 根据变量名称找读取出来的内容
                print('$$$$====result===', result)
                print('####data#####' , data)
                print('####value#####', value)
                print ('=============+=======123444',result)
                G_context().update_dict(result)

    @allure.step("全量断言-对比两个Json的差异")
    def assert_json_DeepDiff(self, **kwargs):
        """
        对比两个json的差异
        :param json1: 期望结果
        :param json2: 实际结果
        :param exclude_paths:需要排除的字段，集合的类型，比如{“id”,...}
        :param ignore_order: 忽略顺序，一般用户有序数据类型，比如列表
        :param ignore_string_case:忽略值的大小写，False
        :return: 当数据没有差异则返回空集合

        """
        try:
            json1 = kwargs["json1"]
            json2 = kwargs["json2"]

            exclude_paths = kwargs.get("过滤字段", False)
            ignore_order = kwargs.get("忽略顺序", False)
            ignore_string_case = kwargs.get("忽略大小写", False)

            screen_data = {"exclude_paths": exclude_paths, "ignore_order": ignore_order,
                       "ignore_string_case": ignore_string_case}

            diff = DeepDiff(json1, json2, **screen_data)
        except Exception  as e:
            assert  False ,  f"全量断言失败，代码报错{e}"

        assert not diff, f"全量断言失败:{diff}"

        # TODO: 扩展 - 数据库提取的方法


    @allure.step ("获取testcase中的关键信息，驱动请求")
    def request_post_from_data(self,**kwargs):
        url = kwargs.get('URL', None)
        params = kwargs.get('PARAMS', None)
        headers = kwargs.get('HEADERS', None)
        data = kwargs.get('DATA', None)
        key_data = {'url':url,
                    'params':params,
                    'data':data,
                    'headers':headers}
        response=requests.post(**key_data)
        G_context().set_dict('response',response)
        return response





